#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "book.h"

//(内部函数，不对外开放)
// 根据书名，返回book信息节点
Book* _find_book(BookSystem* booksys, char name[])
{
    if (booksys->book_list == NULL || booksys->list_len == 0) {
        return NULL;
    }

    Book* node = booksys->book_list;
    for (int i = 0; i < booksys->list_len; ++i, node = node->next) {
        if (!strcmp(name, node->name)) {
            return node;
        }
    }
    return NULL;
}

//在链表尾部添加书籍信息
_Bool add_book(BookSystem* booksys, char name[], double price, int amount)
{
    Book* info = (Book*)calloc(1, sizeof(Book));
    if (info == NULL) {
        return false;
    }

    strcpy(info->name, name);
    info->price = price;
    info->amount = amount;
    info->prev = NULL;
    info->next = NULL;

    if (booksys->list_len == 0) {
        booksys->book_list = info;
        ++(booksys->list_len);
        return true;
    }

    Book* tmp = booksys->book_list;
    while (tmp->next != NULL) {
        tmp = tmp->next;
    }
    tmp->next = info;
    info->prev = tmp;
    ++(booksys->list_len);
    return true;
}

//删除图书信息
_Bool del_book(BookSystem* booksys, char name[])
{
    Book* info = _find_book(booksys, name);
    if (info == NULL) {
        return false;
    }

    if (info->prev == NULL) {
        booksys->book_list = info->next;
        if (info->next != NULL) {
            info->next->prev = NULL;
        }
    } else if (info->next == NULL) {
        info->prev->next = NULL;
    } else {
        info->prev->next = info->next;
        info->next->prev = info->prev;
    }
    booksys->list_len -= 1;
    free(info);
    return true;
}

//更改图书信息
_Bool change_book(BookSystem* booksys,
                  char old_name[],
                  char new_name[],
                  double new_price,
                  int new_amount)
{
    Book* info = _find_book(booksys, old_name);
    if (info == NULL) {
        return false;
    }
    strcpy(info->name, new_name);
    info->price = new_price;
    info->amount = new_amount;
    return true;
}

//展示所有图书信息
void showall(BookSystem* booksys)
{
    Book* info = booksys->book_list;
    if (booksys->list_len == 0)
        return;
    printf("--------------------------------\n");
    printf("No.\tname\tprice\tamount\n");
    printf("--------------------------------\n");
    for (int i = 1; i <= booksys->list_len; ++i, info = info->next) {
        printf("%d\t%s\t%.2lf\t%d\n", i, info->name, info->price, info->amount);
    }
    printf("--------------------------------\n");
}

//序列化图书信息
_Bool serialize_booksys(BookSystem* booksys)
{
    FILE* file = fopen(FILE_NAME, "wb");
    if (file == NULL) {
        return false;
    }

    Book* tmp = booksys->book_list;
    booksys->book_list = NULL;
    
    if (fwrite(booksys, sizeof(BookSystem), 1, file) == 0) {
        booksys->book_list = tmp;
        fclose(file);
        return false;
    }

    booksys->book_list = tmp; 
    for (Book* node = booksys->book_list; node != NULL; node = node->next) {
        Book* prev = node->prev;
        Book* next = node->next;
        node->prev = NULL;
        node->next = NULL;

        if (fwrite(node, sizeof(Book), 1, file) == 0) {
            node->prev = prev;
            node->next = next;
            fclose(file);
            return false;
        }
        node->prev = prev;
        node->next = next;
    }

    fclose(file);
    return true;
}

//反序列化图书信息
BookSystem* unserialize_booksys(char filename[])
{
    BookSystem* booksys = (BookSystem*)calloc(1, sizeof(BookSystem));
    if (booksys == NULL) {
        free(booksys);
        return NULL;
    }

    FILE* file = fopen(FILE_NAME, "rb");
    if (file == NULL) {
        free(booksys);
        fclose(file);
        return NULL;
    }

    if (fread(booksys, sizeof(BookSystem), 1, file) == 0) {
        free(booksys);
        fclose(file);
        return NULL;
    }

    Book* cur = NULL;
    while (!feof(file)) {
        Book* node = (Book*)calloc(1, sizeof(Book));
        if (fread(node, sizeof(Book), 1, file) == 0) {
            free(node);
            fclose(file);
            break;
        }
        if (booksys->book_list == NULL) {
            booksys->book_list = node;
            node->prev = NULL;
        } else {
            cur->next = node;
            node->prev = cur;
        }
        cur = node;
    }
    return booksys;
}


//释放所有申请的内存空间
void destory_booksys(BookSystem* booksys)
{
    //
    Book* tmp = booksys->book_list;
    if (tmp == NULL) {
        free(booksys);
        return;
    }

    while (tmp->next != NULL) 
        tmp = tmp->next;
    while (tmp->prev != NULL) {
        tmp = tmp->prev;
        free(tmp->next);
    }
    if (booksys->book_list == tmp) {
        free(tmp);
    }
    free(booksys);
}